home *** CD-ROM | disk | FTP | other *** search
- /* OS- and machine-dependent stuff for IBM-PC running MS-DOS and Turbo-C */
- #include <stdio.h>
- #include <dir.h>
- #include <dos.h>
- #include <io.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <process.h>
- #include <fcntl.h>
- #include <alloc.h>
- #include "global.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "iface.h"
- #include "cmdparse.h"
- #include "pc.h"
- #include "proc.h"
-
- static int kbchar __ARGS((void));
- static void kbint __ARGS((void));
-
- unsigned _stklen = 8192;
- int Tick;
-
- /* This flag is set by setirq() if IRQ 8-15 is used, indicating
- * that the machine is a PC/AT with a second 8259 interrupt controller.
- * If this flag is set, the interrupt return code in pcgen.asm will
- * send an End of Interrupt command to the second 8259 as well as the
- * first.
- */
- char Isat;
-
- /* Interface list header */
- struct iface *Ifaces;
-
- static char Ttbuf[BUFSIZ];
- static int saved_break;
-
- /* Keyboard input buffer */
- #define KBSIZE 256
- static struct {
- char buf[KBSIZE];
- char *wp;
- char *rp;
- int cnt;
- } Keyboard;
-
- int
- errhandler(errval,ax,bp,si)
- int errval,ax,bp,si;
- {
- return 3; /* Fail the system call */
- }
-
- /* Called at startup time to set up console I/O, memory heap */
- void
- ioinit(mem)
- int32 mem;
- {
- #ifndef __TURBOC__
- struct sgttyb ttybuf;
- #endif
- /* Ignore ctrl-breaks */
- setvect(0x23,nullvec);
-
- /* Fail all I/O errors */
- harderr(errhandler);
-
- /* Save these two file table entries for something more useful */
- fclose(stdaux);
- #ifdef __TURBOC__
- fclose(stdprn);
- #else
- fclose(stdprt);
- #endif
-
- /* Interrupts use a special stack deep in data space.
- * Calls to sbrk() (invoked by malloc when it needs more memory
- * from the system) at interrupt time will fail because sbrk()
- * will think that the stack has overwritten the heap. So
- * grab all the memory we can now for the heap so that malloc
- * won't have to call sbrk and alloc_mbuf() won't fail unnecessarily
- * at interrupt time.
- */
- #ifdef LARGEDATA
- grabcore(mem);
- #else
- grabcore(mem);
- #endif
-
- setbuf(stdout,Ttbuf);
- #ifdef __TURBOC__
- saved_break = getcbrk();
- setcbrk(0);
- ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20); /* put stdout in raw mode */
- #else
- /* Put display in raw mode. Note that this breaks tab expansion,
- * so you need to run NANSI.SYS or equivalent.
- */
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags = RAW;
- ioctl(1,TIOCSETP,&ttybuf);
- #endif
- /* Link timer handler into timer interrupt chain */
- chtimer(btick);
-
- /* Find out what multitasker we're running under, if any */
- chktasker();
-
- /* Initialize keyboard queue */
- Keyboard.rp = Keyboard.wp = Keyboard.buf;
-
- }
- /* Called just before exiting to restore console state */
- void
- iostop()
- {
- #ifndef __TURBOC__
- struct sgttyb ttybuf;
- #endif
-
- setbuf(stdout,NULLCHAR);
- #ifdef __TURBOC__
- setcbrk(saved_break);
- ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20); /* put stdout in cooked mode */
- #else
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags &= ~RAW;
- ioctl(1,TIOCSETP,&ttybuf);
- #endif
- while(Ifaces != NULLIF){
- if(Ifaces->stop != NULLFP)
- (*Ifaces->stop)(Ifaces);
- Ifaces = Ifaces->next;
- }
- /* Unlink timer handler from timer chain */
- uchtimer();
- }
- /* Spawn subshell */
- int
- doshell(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char *command;
- int ret;
- #ifdef __TURBOC__
-
- ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff & ~0x20); /* put stdout in cooked mode */
- if((command = getenv("COMSPEC")) == NULLCHAR)
- command = "/COMMAND.COM";
- ret = spawnv(P_WAIT,command,argv);
-
- ioctl(fileno(stdout), 1, ioctl(fileno(stdout), 0) & 0xff | 0x20); /* put stdout in raw mode */
- return ret;
- #else
- struct sgttyb ttybuf,ttysav;
-
- ioctl(1,TIOCGETP,&ttysav);
- ioctl(1,TIOCGETP,&ttybuf);
- ttybuf.sg_flags &= ~RAW;
- ioctl(1,TIOCSETP,&ttybuf);
-
- if((command = getenv("COMSPEC")) == NULLCHAR)
- command = "/COMMAND.COM";
- ret = fexecl(command,command,NULLCHAR);
- ioctl(1,TIOCSETP,&ttysav);
- if(ret == -1)
- return -1;
- else
- return wait();
- #endif
- }
-
- /* Keyboard interrupt handler */
- static void
- kbint()
- {
- int sig = 0;
- int c;
-
- while((c = kbraw()) != -1 && Keyboard.cnt < KBSIZE){
- sig = 1;
- *Keyboard.wp++ = c;
- if(Keyboard.wp == &Keyboard.buf[KBSIZE])
- Keyboard.wp = Keyboard.buf;
- Keyboard.cnt++;
- }
- if(sig){
- psignal(&Keyboard,1);
- }
- }
- static int
- kbchar()
- {
- char i_state;
- char c;
-
- i_state = dirps();
- while(Keyboard.cnt == 0)
- pwait(&Keyboard);
- c = *Keyboard.rp++;
- if(Keyboard.rp == &Keyboard.buf[KBSIZE])
- Keyboard.rp = Keyboard.buf;
- Keyboard.cnt--;
- restore(i_state);
- return c;
- }
- /* Read characters from the keyboard, translating them to "real" ASCII.
- * If none are ready, block. The F-10 key is special; translate it to -2.
- */
- int
- kbread()
- {
- int c;
-
- if((c = kbchar()) == 0){
- /* Lead-in to a special char */
- c = kbchar();
- switch(c){
- case 3: /* NULL (bizzare!) */
- c = 0;
- break;
- case 68: /* F-10 key (used as command-mode escape) */
- c = -2;
- break;
- case 83: /* DEL key */
- c = 0x7f;
- break;
- default: /* Dunno what it is */
- c = -1;
- }
- }
- return c;
- }
-
- /* Called from the timer routine on each tick */
- void
- systick()
- {
- /* Tickle the keyboard interrupt. This nonsense is
- * necessary because there's no way to get a hardware interrupt
- * from the BIOS.
- */
- kbint();
-
- /* Flush out console. This gains efficiency in telnet
- * since it only handles a character at a time, at the cost
- * of a slight echo delay.
- */
- fflush(stdout);
- }
- /* Install hardware interrupt handler.
- * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
- * Note that bus line IRQ2 maps to IRQ9 on the AT
- */
- int
- setirq(irq,handler)
- unsigned irq;
- INTERRUPT (*handler)();
- {
- /* Set interrupt vector */
- if(irq < 8){
- setvect(8+irq,handler);
- } else if(irq < 16){
- Isat = 1;
- setvect(0x70 + irq - 8,handler);
- } else {
- return -1;
- }
- return 0;
- }
- /* Return pointer to hardware interrupt handler.
- * Takes IRQ numbers from 0-7 (0-15 on AT) and maps to actual 8086/286 vectors
- */
- INTERRUPT
- (*getirq(irq))()
- unsigned int irq;
- {
- /* Set interrupt vector */
- if(irq < 8){
- return getvect(8+irq);
- } else if(irq < 16){
- return getvect(0x70 + irq - 8);
- } else {
- return NULLVIFP;
- }
- }
- /* Disable hardware interrupt */
- int
- maskoff(irq)
- unsigned irq;
- {
- if(irq < 8){
- setbit(0x21,(char)(1<<irq));
- } else if(irq < 16){
- irq -= 8;
- setbit(0xa1,(char)(1<<irq));
- } else {
- return -1;
- }
- return 0;
- }
- /* Enable hardware interrupt */
- int
- maskon(irq)
- unsigned irq;
- {
- if(irq < 8){
- clrbit(0x21,(char)(1<<irq));
- } else if(irq < 16){
- irq -= 8;
- clrbit(0xa1,(char)(1<<irq));
- } else {
- return -1;
- }
- return 0;
- }
- /* Return 1 if specified interrupt is enabled, 0 if not, -1 if invalid */
- int
- getmask(irq)
- unsigned irq;
- {
- if(irq < 8)
- return (inportb(0x21) & (1 << irq)) ? 0 : 1;
- else if(irq < 16){
- irq -= 8;
- return (inportb(0xa1) & (1 << irq)) ? 0 : 1;
- } else
- return -1;
- }
- /* Called from assembler stub linked to BIOS interrupt 1C, called on each
- * hardware clock tick. Signal a clock tick to the timer process.
- */
- void
- ctick()
- {
- Tick++;
- psignal(&Tick,1);
- }
- /* Set bit(s) in I/O port */
- void
- setbit(port,bits)
- unsigned port;
- char bits;
- {
- outportb(port,(char)inportb(port)|bits);
- }
- /* Clear bit(s) in I/O port */
- void
- clrbit(port,bits)
- unsigned port;
- char bits;
- {
- outportb(port,(char)(inportb(port) & ~bits));
- }
- /* Convert a pointer to a long integer */
- long
- ptol(p)
- void *p;
- {
- long x;
-
- x = FP_OFF(p);
- #ifdef LARGEDATA
- x |= (long)FP_SEG(p) << 16;
- #endif
- return x;
- }
- void *
- ltop(l)
- long l;
- {
- register unsigned seg,offset;
-
- seg = l >> 16;
- offset = l;
- return MK_FP(seg,offset);
- }
- void
- sysreset()
- {
- void (*foo) __ARGS((void));
-
- foo = MK_FP(0xffff,0); /* FFFF:0000 is hardware reset vector */
- (*foo)();
- }
-
-